#include "networkthread.h"
#include <QDebug>

using namespace Moolink;

NetWorkThread::NetWorkThread(QObject *parent) :
    QThread(parent)
{

}

//! [0]
NetWorkThread::~NetWorkThread()
{
    m_mutex.lock();
    m_quit = true;
    m_cond.wakeOne();
    m_mutex.unlock();
    wait();
}
//! [0]

//! [1] //! [2]
void NetWorkThread::transaction(const int hostIndex,const QString &hostName,const QString &hostIp,const int hostPort,int waitTimeout, const QString &request)
{
//! [1]
    const QMutexLocker locker(&m_mutex_wait);
    m_mutex.lock();
    m_host.hostIndex=hostIndex;
    m_host.hostName=hostName;
    m_host.HostIp=hostIp;
    m_host.HostPort=hostPort;
    m_waitTimeout = waitTimeout;
    //m_connentfail_cnt=0;
    m_request.enqueue(request);
    m_mutex.unlock();

//! [3]
    if (!isRunning())
        start();
    else
        m_cond.wakeOne();
}
//! [2] //! [3]

//! [4]
void NetWorkThread::run()
{

    int threadWaitTime=500;
//    m_mutex.lock();


//    m_mutex.unlock();


    QTcpSocket tcpClient;


    while (!m_quit) {

        //qDebug()<<"NetWorkThread\r\n";
        //tcpClient.disconnectFromHost();
        if (tcpClient.state() == QAbstractSocket::ConnectedState)  //已断开连接则进入if{}
        {
            threadWaitTime=500;

            m_mutex.lock();
            if(!(m_request.isEmpty())) {tcpClient.write(m_request.dequeue().toLatin1());  threadWaitTime=m_waitTimeout;}//qt5出去了.toAscii()
            m_mutex.unlock();
            if (tcpClient.waitForReadyRead(threadWaitTime)) {
                QByteArray responseData = tcpClient.readAll();
//                while (tcpClient.waitForReadyRead(50))
//                    responseData += tcpClient.readAll();

                const QString response = QString::fromUtf8(responseData);
                if(response.startsWith("##")&&response.endsWith("\r\n")) emit this->response2(m_host.hostIndex,m_host.hostName,response);

            }
            else if(threadWaitTime>500)
            {
                emit this->error(m_host.hostIndex,m_host.hostName,"E01:等待回复超时,不需要回复时请将等待时间设置为500ms,将不会返回本错误");
            }

            m_mutex.lock();
            m_connentfail_cnt=0;
            if(!(m_request.isEmpty()))
            {
                m_mutex.unlock();
                msleep(500);//发送轮次延时防止服务器粘包
            }
            else
            {
                 m_mutex.unlock();
                msleep(100);//接收轮询延时降低客户机负荷
            }

        }
        else if(tcpClient.state() == QAbstractSocket::UnconnectedState || tcpClient.waitForDisconnected(1000))
        {
            m_mutex.lock();
            tcpClient.connectToHost(m_host.HostIp, m_host.HostPort);
            m_mutex.unlock();
            if (tcpClient.waitForConnected(1000))  // 连接成功则进入if{}
            {
//                tcpClient.write(m_request.toLatin1()); //qt5出去了.toAscii()
//                qDebug()<<"NetWorkThread:连接成功,数据已发送,但首发可能收不到,待分析\r\n";
            }
            else
            {
                msleep(1000);//连接失败时重试间隔延时
                //qDebug()<<"NetWorkThread:connectToHost Timeout\r\n";
                m_mutex.lock();
                if(m_connentfail_cnt<1)
                {
                    m_connentfail_cnt++;
                    emit this->error(m_host.hostIndex,m_host.hostName,"E02:连接失败,待发送指令数:"+QString::number(m_request.size())+",正在尝试重连"+QString::number(m_connentfail_cnt));
                    m_mutex.unlock();
                }
                else
                {
                    m_request.clear(); m_connentfail_cnt=0;
                    emit this->error(m_host.hostIndex,m_host.hostName,"E03:连接失败,等待下次指令再重连,指令缓冲队列已清空");//待发送指令数:"+QString::number(m_request.size()));
                    m_mutex.unlock();
                    m_mutex_wait.lock();
                    m_cond.wait(&m_mutex_wait);
                    m_mutex_wait.unlock();
                }

            }
        }





    }
//! [13]
}
